# -*- coding: UTF-8 -*-
"""
@Project ：swift-forge-engine 
@File    ：build_tree.py
@IDE     ：PyCharm 
@Author  ：Tony.Gan
@Date    ：2025/2/24 1:17 
@Des     ：
"""
from datetime import datetime
from typing import Any, Sequence

from App.utils.enums import BuildTreeType
from App.utils.serializers import RowData, select_list_serialize


def get_tree_nodes(row: Sequence[RowData]) -> list[dict[str, Any]]:
    """获取所有树形结构节点"""
    tree_nodes = select_list_serialize(row)
    # 时间字段格式化处理
    for node in tree_nodes:
        for key in list(node.keys()):  # 使用list避免遍历时修改字典
            value = node[key]
            # 处理字符串类型时间字段（如：2023-01-01T12:00:00）
            if isinstance(value, str) and ('_time' in key or '_at' in key):
                try:
                    # 移除可能的毫秒部分并转换
                    dt = datetime.fromisoformat(value.replace('Z', '').split('.')[0])
                    node[key] = dt.strftime("%Y-%m-%d %H:%M:%S")
                except (ValueError, TypeError):
                    pass
            # 处理datetime对象类型
            elif isinstance(value, datetime):
                node[key] = value.strftime("%Y-%m-%d %H:%M:%S")
    tree_nodes.sort(key=lambda x: x['sort'])
    return tree_nodes


def traversal_to_tree(nodes: list[dict[str, Any]]) -> list[dict[str, Any]]:
    """
    通过遍历算法构造树形结构

    :param nodes:
    :return:
    """
    tree = []
    node_dict = {node['id']: node for node in nodes}

    for node in nodes:
        parent_id = node['parent_id']
        if parent_id is None:
            tree.append(node)
        else:
            parent_node = node_dict.get(parent_id)
            if parent_node is not None:
                if 'children' not in parent_node:
                    parent_node['children'] = []
                if node not in parent_node['children']:
                    parent_node['children'].append(node)
            else:
                if node not in tree:
                    tree.append(node)

    return tree


def recursive_to_tree(nodes: list[dict[str, Any]], *, parent_id: int | None = None) -> list[dict[str, Any]]:
    """
    通过递归算法构造树形结构（性能影响较大）

    :param nodes:
    :param parent_id:
    :return:
    """
    tree = []
    for node in nodes:
        if node['parent_id'] == parent_id:
            child_node = recursive_to_tree(nodes, parent_id=node['id'])
            if child_node:
                node['children'] = child_node
            tree.append(node)
    return tree


def get_tree_data(
    row: Sequence[RowData], build_type: BuildTreeType = BuildTreeType.traversal, *, parent_id: int | None = None
) -> list[dict[str, Any]]:
    """
    获取树形结构数据

    :param row:
    :param build_type:
    :param parent_id:
    :return:
    """
    nodes = get_tree_nodes(row)
    match build_type:
        case BuildTreeType.traversal:
            tree = traversal_to_tree(nodes)
        case BuildTreeType.recursive:
            tree = recursive_to_tree(nodes, parent_id=parent_id)
        case _:
            raise ValueError(f'无效的算法类型：{build_type}')
    return tree


# 转换按钮为 authList 格式
def convert_buttons_to_auth_list(menu_tree: list) -> list:
    for node in menu_tree:
        if "children" in node and node["children"]:
            # 递归处理子节点
            node["children"] = convert_buttons_to_auth_list(node["children"])

            # 筛选出按钮类型且为字典的子节点
            button_nodes = [
                {"id": child["id"], "title": child["name"], "auth_mark": child["perms"]}
                for child in node["children"]
                if isinstance(child, dict) and child.get("menu_type") == 2
            ]

            if button_nodes:
                node["authList"] = button_nodes
                # 保留非按钮类型的子节点
                node["children"] = [
                    child for child in node["children"]
                    if not (isinstance(child, dict) and child.get("menu_type") == 2)
                ]
    return menu_tree
